package com.apanal.qlife.sys.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.apanal.qlife.common.constants.Constants;
import com.apanal.qlife.common.exception.BusinessException;
import com.apanal.qlife.common.page.Page;
import com.apanal.qlife.common.page.PageReturn;
import com.apanal.qlife.common.shiro.ShiroHelper;
import com.apanal.qlife.common.util.IdWorkerFactory;
import com.apanal.qlife.common.util.MD5Util;
import com.apanal.qlife.common.util.PropertieUtil;
import com.apanal.qlife.sys.dao.UserGroupRelMapper;
import com.apanal.qlife.sys.dao.UserMapper;
import com.apanal.qlife.sys.dao.UserRoleRelMapper;
import com.apanal.qlife.sys.model.Checkcode;
import com.apanal.qlife.sys.model.User;
import com.apanal.qlife.sys.model.UserGroupRel;
import com.apanal.qlife.sys.model.UserRoleRel;
import com.apanal.qlife.sys.service.CheckcodeService;
import com.apanal.qlife.sys.service.FileService;
import com.apanal.qlife.sys.service.GroupService;
import com.apanal.qlife.sys.service.ResourceService;
import com.apanal.qlife.sys.service.RoleService;
import com.apanal.qlife.sys.service.UserService;

/**
 * 用户服务层接口实现类
 * 
 * @author shuliangxing
 * 
 * @date 2015-1-14上午11:37:03
 */
@Service
public class UserServiceImpl implements UserService {

	@Autowired
	UserMapper mapper;

	@Autowired
	FileService fileService;

	@Autowired
	ResourceService resourceService;

	@Autowired
	RoleService roleService;

	@Autowired
	GroupService groupService;

	@Autowired
	UserGroupRelMapper userGroupRelMapper;

	@Autowired
	UserRoleRelMapper userRoleRelMapper;

	@Autowired
	CheckcodeService checkcodeService;

	@Override
	public String deleteById(Long id) {
		mapper.deleteByPrimaryKey(id);
		// 删除所有旧用户角色关联数据
		userRoleRelMapper.deletesByUseId(id);
		// 删除所有旧用户群组关联数据
		userGroupRelMapper.deletesByUseId(id);
		return Constants.DEFAULT_MSG_SUCCESS;
	}

	@Override
	public String insert(User record) {
		// 生成用户账号
		record.setUseId(IdWorkerFactory.nextId());
		record.setUseName(Constants.USER_PRE_SYS + IdWorkerFactory.nextId());
		record.setUsePassword(MD5Util.getMD5(Constants.USER_DEFAULT_PSW));
		record.setUseType(Constants.USER_TYPE_ADMIN);
		mapper.insert(record);
		// 如果角色id字符串不为空,则新增用户角色关联表数据
		if (record.getRolIds() != null && !"".equals(record.getRolIds())) {
			String[] idArray = record.getRolIds().split(",");
			List<UserRoleRel> list = new ArrayList<UserRoleRel>();
			for (String rolId : idArray) {
				UserRoleRel rel = new UserRoleRel();
				rel.setRelId(IdWorkerFactory.nextId());
				rel.setUseId(record.getUseId());
				rel.setRolId(Long.valueOf(rolId));
				rel.setInsertBy(record.getInsertBy());
				list.add(rel);
			}
			if (!list.isEmpty()) {
				userRoleRelMapper.inserts(list);
			}
		}

		// 新增用户群组关联数据
		if (record.getGroIds() != null && !"".equals(record.getGroIds())) {
			// 新增关联数据
			String[] idArray = record.getGroIds().split(",");
			List<UserGroupRel> list = new ArrayList<UserGroupRel>();
			for (String groId : idArray) {
				UserGroupRel rel = new UserGroupRel();
				rel.setRelId(IdWorkerFactory.nextId());
				rel.setUseId(record.getUseId());
				rel.setGroId(Long.valueOf(groId));
				rel.setInsertBy(record.getInsertBy());
				list.add(rel);
			}
			if (!list.isEmpty()) {
				userGroupRelMapper.inserts(list);
			}
		}
		return Constants.DEFAULT_MSG_SUCCESS;
	}

	@Override
	public String insertSelective(User record) {
		mapper.insertSelective(record);
		return Constants.DEFAULT_MSG_SUCCESS;
	}

	@Override
	public User selectById(Long useId) {
		return mapper.selectByPrimaryKey(useId);
	}

	/**
	 * 修改用户信息
	 * 
	 * @param record
	 * @param request
	 * @return
	 */
	@Override
	public String updateByIdSelective(User record) {
		mapper.updateByPrimaryKeySelective(record);
		// 删除所有旧用户角色关联数据
		userRoleRelMapper.deletesByUseId(record.getUseId());
		// 新增用户角色关联数据
		if (record.getRolIds() != null && !"".equals(record.getRolIds())) {
			// 新增关联数据
			String[] idArray = record.getRolIds().split(",");
			List<UserRoleRel> list = new ArrayList<UserRoleRel>();
			for (String rolId : idArray) {
				UserRoleRel rel = new UserRoleRel();
				rel.setRelId(IdWorkerFactory.nextId());
				rel.setUseId(record.getUseId());
				rel.setRolId(Long.valueOf(rolId));
				rel.setInsertBy(record.getLastUpdateBy());
				list.add(rel);
			}
			if (!list.isEmpty()) {
				userRoleRelMapper.inserts(list);
			}
		}

		// 删除所有旧用户群组关联数据
		userGroupRelMapper.deletesByUseId(record.getUseId());
		// 新增用户群组关联数据
		if (record.getGroIds() != null && !"".equals(record.getGroIds())) {
			// 新增关联数据
			String[] idArray = record.getGroIds().split(",");
			List<UserGroupRel> list = new ArrayList<UserGroupRel>();
			for (String groId : idArray) {
				UserGroupRel rel = new UserGroupRel();
				rel.setRelId(IdWorkerFactory.nextId());
				rel.setUseId(record.getUseId());
				rel.setGroId(Long.valueOf(groId));
				rel.setInsertBy(record.getLastUpdateBy());
				list.add(rel);
			}
			if (!list.isEmpty()) {
				userGroupRelMapper.inserts(list);
			}
		}
		return Constants.DEFAULT_MSG_SUCCESS;
	}

	@Override
	public String updateById(User record) {
		mapper.updateByPrimaryKey(record);
		return Constants.DEFAULT_MSG_SUCCESS;
	}

	@Override
	public List<User> selectAll() {
		return mapper.select(null);
	}

	@Override
	public User selectRelationById(Long id) {
		User param = new User();
		param.setUseId(id);
		User user = mapper.selectRelation(param).get(0);
		// 倒序排列子集合,使顺序与列表页面、弹出选择页面顺序保持一致
		Collections.reverse(user.getRolList());
		Collections.reverse(user.getGroList());
		return user;
	}

	@Override
	public PageReturn<User> selectRelationForPage(User entity, Page page) {
		entity.setUseType(Constants.USER_TYPE_ADMIN);
		int count = mapper.selectRelationForPageCount(entity, page);
		List<User> list = mapper.selectRelationForPage(entity, page);
		for (User user : list) {
			user.setRolList(roleService.selectByUseId(user.getUseId()));
			user.setGroList(groupService.selectByUseId(user.getUseId()));
		}
		return new PageReturn<User>(list, count, page, entity);
	}

	@Override
	public String deleteSoft(Long useId, Long operationId) {
		User entity = new User();
		entity.setUseId(useId);
		entity.setLastUpdateBy(operationId);
		entity.setStatus(Constants.IS_VALID_FALSE);
		mapper.updateByPrimaryKeySelective(entity);
		return Constants.DEFAULT_MSG_SUCCESS;
	}

	@Override
	public String changePassword(Long userId, String newPassword) {
		User user = new User();
		user.setUseId(userId);
		user.setUsePassword(MD5Util.getMD5(newPassword));
		user.setLastUpdateBy(userId);
		mapper.updateByPrimaryKeySelective(user);
		return Constants.DEFAULT_MSG_SUCCESS;
	}

	@Override
	public User findByUsername(String username) {
		if (username == null || "".equals(username.trim())) {
			return null;
		}
		User user = new User();
		user.setUseName(username);
		user.setUseType(Constants.USER_TYPE_ADMIN);
		List<User> list = mapper.select(user);
		if (list == null || list.isEmpty()) {
			return null;
		} else {
			return list.get(0);
		}
	}

	@Override
	public User findByMobile(String mobile) {
		if (mobile == null || "".equals(mobile.trim())) {
			return null;
		}
		User user = new User();
		user.setUseMobilePhone(mobile);
		user.setUseType(Constants.USER_TYPE_ADMIN);
		List<User> list = mapper.select(user);
		if (list == null || list.isEmpty()) {
			return null;
		} else {
			return list.get(0);
		}
	}

	@Override
	public String selectUserNameById(Long id) {
		if (id == null) {
			return null;
		}
		// 0表示匿名用户
		if (id == 0) {
			return Constants.ANONYMOUS_USER;
		}
		// 此处需要走代理对象，目的是能走缓存切面
		UserService proxyUserService = (UserService) AopContext.currentProxy();
		return proxyUserService.selectById(id).getUseName();
	}

	@Override
	public String selectUserRealNameById(Long id) {
		if (id == null) {
			return null;
		}
		// 0表示匿名用户
		if (id == 0) {
			return Constants.ANONYMOUS_USER;
		}
		// 此处需要走代理对象，目的是能走缓存切面
		UserService proxyUserService = (UserService) AopContext.currentProxy();
		return proxyUserService.selectById(id).getUseRealName();
	}

	@Override
	public User getCurrentUser() {
		String username = (String) SecurityUtils.getSubject().getPrincipal();
		if (StringUtils.isEmpty(username)) {
			return null;
		}
		// 此处需要走代理对象，目的是能走缓存切面
		UserService proxyUserService = (UserService) AopContext.currentProxy();
		return proxyUserService.findByUsername(username);
	}

	@Override
	public Long getCurrentUserId() {
		User user = this.getCurrentUser();
		if (user == null) {
			return null;
		}
		return user.getUseId();
	}

	@Override
	public List<User> selectByGroId(Long groId) {
		return mapper.selectByGroId(groId);
	}

	@Override
	public List<User> selectByIds(String ids) {
		if (ids == null || "".equals(ids)) {
			return null;
		} else {
			User param = new User();
			param.setUseIds(ids);
			return mapper.select(param);
		}
	}

	@Override
	public String updateToLockOrUnLock(Long useId, Integer useLocked,
			Long operationId) {
		User user = new User();
		user.setUseId(useId);
		user.setUseLocked(useLocked == Constants.LOCKED_TRUE ? Constants.LOCKED_FALSE
				: Constants.LOCKED_TRUE);
		user.setLastUpdateBy(operationId);
		mapper.updateByPrimaryKeySelective(user);

		// 如果是锁定操作,则设置用户被锁标识
		if (user.getUseLocked() == Constants.LOCKED_TRUE) {
			String username = selectUserNameById(useId);
			List<Session> sessionList = ShiroHelper.getSession(username);
			for (Session session : sessionList) {
				// 设置用户被锁标识
				session.setAttribute(Constants.SESSION_USER_LOCKED_KEY, true);
			}
		}

		return Constants.DEFAULT_MSG_SUCCESS;
	}

	@Override
	public Boolean checkMobileExist(Long useId, String mobile) {
		Boolean result = false;
		User user = new User();
		user.setUseMobilePhone(mobile);
		user.setUseType(Constants.USER_TYPE_ADMIN);
		List<User> list = mapper.select(user);

		// 用户id大于0,表示修改校验,排除当前号码
		if (useId > 0) {
			for (User u : list) {
				if (!u.getUseId().equals(useId)) {
					result = true;
					break;
				}
			}
		}
		// 表示新增校验
		else {
			result = !list.isEmpty();
		}
		return result;
	}

	@Override
	public String resetPwd(Long useId, Long operationId) {
		User user = new User();
		user.setUseId(useId);
		user.setUsePassword(MD5Util.getMD5(Constants.USER_DEFAULT_PSW));
		user.setLastUpdateBy(operationId);
		mapper.updateByPrimaryKeySelective(user);
		return Constants.DEFAULT_MSG_SUCCESS;
	}

	@Override
	public int checkPwdEqual(Long useId, String password) {
		// 此处需要走代理对象，目的是能走缓存切面
		UserService proxyUserService = (UserService) AopContext.currentProxy();
		User user = proxyUserService.selectById(useId);
		return user.getUsePassword().equals(MD5Util.getMD5(password)) ? 1 : 0;
	}

	@Override
	public String changePwdByCode(String mobile, String newPassword,
			String code, int type) {
		Checkcode checkcode = checkcodeService.findNearestCode(mobile, code, 1);
		if (checkcode != null) {
			// 验证码有效时间,单位毫秒
			int validTime = Integer.valueOf(PropertieUtil
					.getPropertie("FORGET_PWD_VALID_TIME")) * 60 * 1000;
			Date now = new Date();
			long time = now.getTime() - checkcode.getCodSendTime().getTime();
			if (time > validTime) {
				throw new BusinessException("验证码已失效");
			} else if (checkcode.getCodUsed()) {
				throw new BusinessException("验证码已被使用");
			} else {
				User user = new User();
				user.setUseMobilePhone(mobile);
				user.setUseType(type);
				user = mapper.select(user).get(0);

				// 此处需要走代理对象，目的是能走缓存切面
				UserService proxyUserService = (UserService) AopContext
						.currentProxy();
				// 修改密码
				proxyUserService.changePassword(user.getUseId(), newPassword);
				// 改变验证码状态为已使用
				checkcodeService.changeCodeUsed(checkcode.getCodId());
			}
		} else {
			throw new BusinessException("验证码不正确");
		}
		return "修改密码成功";
	}

	@Override
	public void setLoginUserOrgDisableFlag(Long orgId) {
		List<Session> sessionList = ShiroHelper.getSession(orgId);
		for (Session session : sessionList) {
			// 设置登录用户直属机构停用标识
			session.setAttribute(Constants.SESSION_ORG_DISABLE_KEY, true);
		}
	}

}
